//
//  HMUtils.swift
//  HealthMonitoring
//
//  Created by 珠海正杰 on 2018/4/8.
//  Copyright © 2018年 YTYanK. All rights reserved.
//
/****
 *  工具类 
 */


import UIKit
import SDWebImage
import FLKAutoLayout
import SwiftyJSON // 依赖比较严重
import Toast
//import Tactile
import RKDropdownAlert

//控件的事件联系
public let UIControlEventsTouchUpInside = UIControlEvents.touchUpInside
public let UIControlStateNormal = UIControlState.normal
public let UIControlStateSelected = UIControlState.selected
public let UIControlStateHighlighted = UIControlState.highlighted

/// 数组字典 Array<NSDictionary>
public typealias NSInfoArray = Array<NSDictionary>

public typealias HMNormalBlock = () -> ()
public class HMUtils: NSObject, MBProgressHUDDelegate {
    private var utilsHUD: MBProgressHUD?
    
    static let share: HMUtils = {
        let _utils  = HMUtils()
        return _utils
    }()
    
    /// 加载等待
    public func showHUD(_ target: AnyObject) {
//        let selfHud = target as! UIViewController
        let app =  UIApplication.shared.delegate as! AppDelegate
        let hud = MBProgressHUD.showAdded(to: app.window!, animated: true)
        hud.delegate = HMUtils.share
        hud.bezelView.color = UIColor.clear
        hud.label.text = "请稍等"
        hud.backgroundView.style = .blur
        //        hud.hide(animated: true, afterDelay: 2)
        utilsHUD = hud
    }
    
    public func showHUD(_ title: String) {
        let app =  UIApplication.shared.delegate as! AppDelegate
        let hud = MBProgressHUD.showAdded(to: app.window!, animated: true)
        hud.delegate = HMUtils.share
        hud.bezelView.color = UIColor.black
        hud.opacity = 1  // 设置背景框的透明度 默认0.8
        // 设置背景框的背景颜色和透明度， 设置背景颜色之后opacity属性的设置将会失效
//        hud.color = UIColor.blue
        hud.label.text = title
        hud.label.textColor = UIColor.white
//        hud.backgroundView.style = .blur
        hud.backgroundColor = .clear
        // 设置菊花颜色  只能设置菊花的颜色
        hud.activityIndicatorColor = UIColor.white
        
        // 设置提示框的相对于父视图中心点的便宜，正值 向右下偏移，负值左上
//        hud.xOffset = -80;
//        hud.yOffset = -100;
        //,设置隐藏的时候是否从父视图中移除，默认是NO
//        hud.removeFromSuperViewOnHide = NO;
        // 隐藏时候的回调 隐藏动画结束之后
        hud.completionBlock = {
          
        };
        utilsHUD = hud
    }
    
    public func hideHUD() {
        if self.utilsHUD != nil {
         self.utilsHUD!.hide(animated: true)
        }
    }
}


// MARK: - 倒计时按钮
public extension UIButton {
    public func countdownButton(second: NSInteger, title: String) {
        
        isEnabled = false
        let defaultColor = self.backgroundColor
        let defaultTitleColor = self.titleLabel?.textColor
        setTitleColor(UIColor.gray, for: .normal)
//        backgroundColor = UIColor.gray
         // 设置倒计时,按钮背景颜色
        var remainingCount = second {
            willSet {
                setTitle("\(newValue)s", for: .normal)
                if newValue <= 0 {
                    setTitle(title, for: .normal)
                }
            }
        }
        // 在global线程里创建一个时间源
        let codeTimer = DispatchSource.makeTimerSource(flags: DispatchSource.TimerFlags.strict, queue: DispatchQueue.global())
        // 设定这个时间源是每秒循环一次，立即开始
        codeTimer.schedule(deadline: .now(), repeating: .seconds(1))
        // 设定时间源的触发事件
        codeTimer.setEventHandler(handler: {
            
            // 返回主线程处理一些事件，更新UI等等
            DispatchQueue.main.async {
                // 每秒计时一次
                remainingCount -= 1
                
                // 时间到了取消时间源
                if remainingCount <= 0 {
                    self.backgroundColor = defaultColor
                    self.setTitleColor(defaultTitleColor, for: .normal)
                    self.isEnabled = true
                    codeTimer.cancel()
                }
            }
        })
        
         // 启动时间源
        codeTimer.resume()
    }
}


// MARK: - 什么鬼？
public extension NSDictionary {
    public var id: Int {
        if let tmp = self["id"] as? Int {
            return tmp
        }
        return -1
    }
}

public extension NSObject {
    ///

     /// 字典转换为JSONString
     /// - Parameter _ dictionary
     /// - Returns: String
     /// - Throws: NSObject
    public func getJSONString(_ dictionary: Dictionary<String, Any>) -> String {
        var jsonStr = ""
        
        let options =  JSONSerialization.WritingOptions.prettyPrinted    //: NSJSONWritingOptions(rawValue: 0)
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: dictionary, options: options)
            if let jsonString = String.init(data: jsonData, encoding: String.Encoding.utf8) {
                jsonStr = jsonString
            }
            
        }catch {
             jsonStr = ""
        }
        return jsonStr
    }
    /// 数组转换为JSONString
    /// - Parameter _ dictionary
    /// - Returns: String
    /// - Throws: NSObject
    public func getJSONString(array: Array<Any>) -> String {
        var jsonStr = ""
        
        let options =  JSONSerialization.WritingOptions.prettyPrinted    //: NSJSONWritingOptions(rawValue: 0)
        do {
            let jsonData = try JSONSerialization.data(withJSONObject: array, options: options)
            if let jsonString = String.init(data: jsonData, encoding: String.Encoding.utf8) {
                jsonStr = jsonString
            }
            
        }catch {
            jsonStr = ""
        }
        return jsonStr
    }
    
    /// JSONString转换为字典
    /// - Parameter _ dictionary
    /// - Returns: String
    public func getJSONStringToDictionary(JSONString: String!) -> Dictionary<String, Any> {
        if let data = JSONString.data(using: String.Encoding.utf8) {
            do {
                return try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.allowFragments) as! Dictionary<String, Any>
            } catch let error as NSError {
                print("\(error) --> HMUtils")
            }
        }
        return Dictionary.init()
    }
    
    // count 秒数
    public func firingTimeCount(count: Int, operate:@escaping (_ timer: DispatchSourceTimer,_ timeCount: Int) -> ()) {
     
        var timeCount = count
        // 在global线程里创建一个时间源
        let codeTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
        // 设定这个时间源是每秒循环一次，立即开始
        codeTimer.schedule(deadline: .now(), repeating: .seconds(1))
         // 设定时间源的触发事件
        codeTimer.setEventHandler {
            // 每秒计时一次
            timeCount = timeCount - 1
            
            if timeCount <= 0 {
                codeTimer.cancel()
            }
            
            // 返回主线程处理一些事件，更新UI等等
            DispatchQueue.main.async {
                operate(codeTimer, timeCount)
            }
        }
         // 启动时间源
        codeTimer.resume()
        //        codeTimer.suspend()//定时器暂停；
        
        //        codeTimer.cancel()//定时器取消，会销毁；
        
        //        codeTimer.activate()//定时器开始激活  此方法需要在 iOS10以上才有
        
        //        codeTimer.resume()//定时器继续
    }
    
}



// MARK: - autoLayout
public extension UIView {
    
    //TODO: 相当对视图布局 - 将此视图的边缘对齐到另一个视图。  //限制两个视图的一个边， 两个视图是包含关系
    /** 左（前）边到 view 左边
     *
     */
    public func leadingAlign(view: UIView, predicate: String = "8") {
        self.alignLeadingEdge(withView: view, predicate: predicate)
    }
    /** 右（前）边到 view 右边
      - view: 相对的view
     */
    public func trailingAlign(view: UIView, predicate: String = "-8") {
        self.alignTrailingEdge(withView: view, predicate: predicate)
    }
    /** 上边到 view 上边
      - view: 相对的view
     */
    public func topAlign(view: UIView, predicate: String = "8") {
        self.alignTopEdge(withView: view, predicate: predicate)
    }
    /** 下边到 view 下边
      - view: 相对的view
     */
    public func bottomAlign(view: UIView, predicate: String = "-8") {
        self.alignBottomEdge(withView: view, predicate: predicate)
    }
    /** 将此视图的x中心对齐到另一个视图。
      - view: 相对的view
     */
    public func centerXAlign(view: UIView, predicate: String = "0") {
        self.alignCenterX(withView: view, predicate: predicate)
    }
    /** 将此视图y的中心对齐到另一个视图。
      - view: 相对的view
     */
    public func centerYAlign(view: UIView, predicate: String = "0") {
        self.alignCenterY(withView: view, predicate: predicate)
    }
    /** 将此视图的x和y的中心对齐到另一个视图。
      - view: 相对的view
     */
    public func centerXYAlign(view: UIView) {
        self.alignCenter(withView: view)
    }
    
    
    //TODO:  视图之间的间隔 - Spacing  horizontally(水平)。//隔开两个视图, 两个视图不是包含关系
    /** 左（前）间距
      - view: 相对的view
     */
    public func leadingHorizontally(view: UIView, predicate: String = "8") {
        self.constrainLeadingSpace(toView: view, predicate: predicate)
    }
//    public func leadingHorizontally(view: UIView, predicate: String = "8") {
//        
//    }
    
    /** 右（后）间距
      - view: 相对的view
     */
    public func trailingHorizontally(view: UIView, predicate: String = "-8") {
        self.constrainTrailingSpace(toView: view, predicate: predicate)
    }
    /** 上间距
      - view: 相对的view
     */
    public func topVertically(view: UIView, predicate: String = "8") {
       self.constrainTopSpace(toView: view, predicate: predicate)
    }
    /** 下间距
      - view: 相对的view
     */
    public func bottomVertically(view: UIView, predicate: String = "0") {
        self.constrainBottomSpace(toView: view, predicate: predicate)
    }
    
    //TODO: 约束视图的宽高
    public func widthConstrain(predicate: String) {
        self.constrainWidth(predicate)
    }
    public func heightConstrain(predicate: String) {
        self.constrainHeight(predicate)
    }
    public func heightConstrainFloat(predicate: String) -> NSLayoutConstraint {
      //  - (NSLayoutConstraint *)constrainHeight:(NSString *)heightPredicate;
        return self.constrainHeight(predicate)
    }
    
    public func width(view: UIView, predicate: String = "0") {
        self.constrainWidth(toView: view, predicate: predicate)
    }
    public func height(view: UIView, predicate: String = "0") {
        self.constrainHeight(toView: view, predicate: predicate)
    }
    public func viewConstrain(wPredicate: String, hPredicate: String) {
        self.constrainWidth(wPredicate, height: hPredicate)
    }
    //约束自我的长宽比
    public func aspectRatio(predicate: String = "") {
        self.constrainAspectRatio(predicate)
    }
    
    public func equalConstrain() {
        if  let view = self.superview {
            self.leadingAlign(view: view, predicate: "0")
            self.trailingAlign(view: view, predicate: "0")
            self.topAlign(view: view, predicate: "0")
            self.bottomAlign(view: view, predicate: "0")
        }
    }
    
    /**
     设置autoLayout
     */
    public func autoLayout() {
        self.setNeedsUpdateConstraints()
        self.updateConstraintsIfNeeded()
    }
    
    public func setupConstraints() {
        self.setNeedsUpdateConstraints()
        self.updateConstraintsIfNeeded()
    }
    
}
// MARK: - get W - H
public extension UIView {
    public var autoWidth: CGFloat {
        return self.systemLayoutSizeFitting(UILayoutFittingCompressedSize).width
    }
    public var autoHeight: CGFloat {
        return self.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height
    }
     /**
      获取整view 宽度
      */
    public var wWidth: CGFloat {
        return self.frame.size.width
    }
    /**
     获取整view 高度
     */
    public var wHeight: CGFloat {
        return self.frame.size.height
    }
    
}

public extension UILabel {
//    public var
    /**
      UILabel 设置缩进
      想要添加缩进的对象
     */
    class func setIndent(_ label: UILabel, alignment: NSTextAlignment, headIndent: CGFloat, tailIndent: CGFloat, lineSpacing: CGFloat) {
        let style = NSMutableParagraphStyle()
        style.alignment = alignment
        style.headIndent = 0.0
        style.firstLineHeadIndent = headIndent
        style.tailIndent = (-1 * tailIndent)
        style.lineSpacing = lineSpacing
        
        var str = ""
        if (label.text != nil) {
            str = label.text!
        }else {
            str = ""
        }
        let attrText = NSAttributedString(string: str, attributes: [NSAttributedStringKey.paragraphStyle: style])
        
       label.attributedText = attrText
    }
}



// MARK: - 添加边框
public extension UIView {
    //
     /**
      * - isAddLayer,  left: Bool, top: Bool, right: Bool, bottom: Bool
      * - color, 颜色
      * - crude, 线条粗细
      */
    func addLayer(isAddLayer: (Bool,Bool,Bool,Bool), color: UIColor, crude: CGFloat, layout: (w: CGFloat, h: CGFloat)?) {
        
        if layout == nil {
            if isAddLayer.0 {
                let lL = CALayer()
                lL.frame = CGRect(x: crude, y: 0, width: crude, height: self.frame.size.height )
                lL.backgroundColor = color.cgColor
                self.layer.addSublayer(lL)
            }
            
            if isAddLayer.1 {
                let tL = CALayer()
                tL.frame = CGRect(x: 0, y: crude, width: self.frame.size.width, height: crude)
                tL.backgroundColor = color.cgColor
                self.layer.addSublayer(tL)
            }
            
            if isAddLayer.2 {
                let rL = CALayer()
                rL.frame = CGRect(x: self.frame.size.width - crude, y: 0, width: crude, height: self.frame.size.height)
                rL.backgroundColor = color.cgColor
                self.layer.addSublayer(rL)
            }
            
            if isAddLayer.3 {
                let bL = CALayer()
                bL.frame = CGRect(x: 0, y: self.frame.size.height - crude, width: self.frame.size.width , height: crude)
                bL.backgroundColor = color.cgColor
                self.layer.addSublayer(bL)
            }
        }else {
            if isAddLayer.0 {
                let lL = CALayer()
                lL.frame = CGRect(x: 0, y: 0, width: crude, height: (layout?.h)!)
                lL.backgroundColor = color.cgColor
                self.layer.addSublayer(lL)
            }
            
            if isAddLayer.1 {
                let tL = CALayer()
                tL.frame = CGRect(x: 0, y: 0, width: (layout?.w)!, height: crude)
                tL.backgroundColor = color.cgColor
                self.layer.addSublayer(tL)
            }
            
            if isAddLayer.2 {
                let rL = CALayer()
                rL.frame = CGRect(x: (layout?.w)!, y: 0, width: crude, height: (layout?.h)!)
                rL.backgroundColor = color.cgColor
                self.layer.addSublayer(rL)
            }
            
            if isAddLayer.3 {
                let bL = CALayer()
                bL.frame = CGRect(x: 0, y: (layout?.h)!, width: (layout?.w)! , height: crude)
                bL.backgroundColor = color.cgColor
                self.layer.addSublayer(bL)
            }
        }
    }
    
    
    // MARK: - Mask
    /**
     *
     * @note 创建背景遮罩
     *
     * @param  this - 需要添加给的View
     * @param action - 事件
     *
     * @return UIView
     *
     * @see creatorMask(view:action:）
     * @see UIView
     */
    public class func createMaskView(this: Any?, action: Selector?)  -> UIView{
        let _mask = UIView()
        let _gesture = UITapGestureRecognizer(target: this, action: action)
        _mask.isUserInteractionEnabled = true
        _mask.addGestureRecognizer(_gesture)
        //        let t = this as! HMViewController
        _mask.frame = CGRect.init(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
        _mask.backgroundColor = UIColor.gray
        _mask.alpha = 0.4
        return _mask
    }
    
    
    
    /// 创建协议按钮
    class func creatorProtocolButton(target:Any?, text: String, btnText: String, font: CGFloat, btnAction: Selector, iconAction: Selector) -> UIView {
        let icon = UIImageView()
        let prefixLable = UILabel()
        let suffixLable = UILabel()
        let btn = UIButton()
        let subV = UIView()
        
        subV.addSubview(icon)
        subV.addSubview(prefixLable)
        subV.addSubview(btn)
        subV.addSubview(suffixLable)
        
        
        
        let w =  UIScreen.main.bounds.size.width - 20
        let prefixWH = String.getTextRectSize(text: "我同意", font: font, size: CGSize.init(width: w, height: 30))
        let btnWH = String.getTextRectSize(text: "《乐众康支付协议》", font: font, size: CGSize.init(width: w, height: 30))
        let suffixWH = String.getTextRectSize(text: "", font: font, size: CGSize.init(width: w, height: 30))
        
        
        
        icon.image = UIImage.init(named: "check_false.png")   //imgName(name: "check_false.png")
        icon.centerYAlign(view: subV)
        icon.leadingAlign(view: subV, predicate: "0")
        icon.heightConstrain(predicate: "20")
        icon.widthConstrain(predicate: "20")
        icon.addTapGesture(target: target, action: iconAction)
        
        prefixLable.centerYAlign(view: subV)
        prefixLable.text = "我同意"
        prefixLable.leadingHorizontally(view: icon, predicate: "10")
        prefixLable.widthConstrain(predicate: "\(prefixWH.width + 8)")
        
        btn.centerYAlign(view: subV)
        btn.leadingHorizontally(view: prefixLable, predicate: "-10")
        btn.widthConstrain(predicate: "\(btnWH.width + 2)")
        btn.setTitleColor(UIColor.black, for: .normal)
        btn.titleLabel?.font = UIFont.systemFont(ofSize: font)
        btn.setTitle("《乐众康支付协议》", for: .normal)
        //        btn.backgroundColor = .red
        btn.addTarget(target, action: btnAction, for: .touchUpInside)
        
        suffixLable.centerYAlign(view: subV)
        suffixLable.leadingHorizontally(view: btn, predicate: "0")
        suffixLable.widthConstrain(predicate: "\(suffixWH.width)")
        suffixLable.text = ""
        
        
        subV.frame.size.width = 20 + 10 + prefixWH.width + 8 + btnWH.width + 2
        return subV
    }
    
    
    
    /**
      添加背景view,显示无数据状态
     */
    class func creatoreBgNullDataView(frame: CGRect) -> UIView {
       let view = UIView.init(frame: frame)
        view.backgroundColor =   configure.shareConfigure.HMColor2 //UIColor.RGBA(r: 0, g: 0, b: 133, a: 1)
       let img = UIImageView()
         view.addSubview(img)
        img.image = UIImage.init(named: "list_null.png")
        img.centerXAlign(view: view)
        img.centerYAlign(view: view, predicate: "-50")
        img.width(view: view)
        
       
       return view
    }
    
}


public extension UIViewController {
    public func showConfirm(title:String = "提示", message:String){
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
        let action = UIAlertAction(title: "确定", style: UIAlertActionStyle.default, handler: { (alertAction) in
        })
        alert.addAction(action)
        self.present(alert, animated: true) {
        }
    }
    
    
    public func showConfirm(title:String = "提示", message:String, confirmText:String, cancelText:String, onConfirm:@escaping HMNormalBlock, onCancel:@escaping HMNormalBlock){
        let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
        let action = UIAlertAction(title: confirmText, style: UIAlertActionStyle.default, handler: { (alertAction) in
            onConfirm()
        })
        let cancel = UIAlertAction(title: cancelText, style: UIAlertActionStyle.default, handler: { (alertAction) in
            onCancel()
        })
        alert.addAction(action)
        alert.addAction(cancel)
        self.present(alert, animated: true) {
        }
    }
    
    /// 提示框
    public func showToast(message: String) {
        UIApplication.shared.keyWindow?.rootViewController?.view.makeToast(message, duration: 2, position: CSToastPositionCenter)
    }
    /// 提示 带图
    public func showToastImage(message: String) {
        UIApplication.shared.keyWindow?.rootViewController?.view.makeToast(message, duration: 2, position: CSToastPositionCenter, title: "", image: UIImage.init(named: "device"), style: nil, completion: { (isBool) in
             //print("xxxxxxxxxxxxxxx")
        })
    }
    /// Nav右按钮

    
    
    
}






// MARK: - NSDictionary
public extension NSDictionary {
    public func toJSON() -> JSON {
        return JSON(self)
    }
}
// MARK: - NSArray
public extension NSArray {
    public func toJSON() -> JSON {
        let json = JSON(self)
        return json
    }
    //<E: Equatable>
    func filterDuplicates<E: Equatable>(_ filter: (Element) -> E) -> [Element]{
        var result = [Element]()
        for value in self {
            let key = filter(value)
            if !result.map({filter($0)}).contains(key) {
                result.append(value)
            }
        }
        return result
    }
}

public extension HMTableViewController {
    
    public func hideFooter(){
        self.tableView.mj_footer.isHidden = true
    }
    
    public func hideHeader(){
        self.tableView.mj_header.isHidden = true
    }
//    public func showToast(message: String){
//        //        self.view.makeToast(message)
//        
//        //        self.view.makeToast("ffffff", duration: 3, position: CSToastPositionTop)
//        
////        UIApplication.shared.keyWindow?.rootViewController?.view.makeToast(message, duration: 2, position: CSToastPositionBottom)
//    }
}

// MARK: - UIColor
public extension UIColor {
    public class func RGBA(r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) -> UIColor {
        let color = UIColor.init(red: r/255.0, green: g/255.0, blue: b/255.0, alpha: a)
        return color
    }
}

// MARK: - String
public extension String {
    /// 手机号验证
    static func isTelNumber(num: String) -> Bool {
        if num.count == 0 {
            return false
        }
        /**
         * 手机号码:
         * 13[0-9], 14[5,7], 15[0, 1, 2, 3, 5, 6, 7, 8, 9], 17[6, 7, 8], 18[0-9], 170[0-9]
         * 移动号段: 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
         * 联通号段: 130,131,132,155,156,185,186,145,176,1709
         * 电信号段: 133,153,180,181,189,177,1700
         */
        let mobile = "^1((3[0-9]|4[57]|5[0-35-9]|7[0678]|8[0-9])\\d{8}$)"
        let cm = "(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)"
        let cu = "(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)"
        let ct = "(^1(33|53|77|8[019])\\d{8}$)|(^1700\\d{7}$)"
        
        let regextestMobile = NSPredicate.init(format: "SELF MATCHES %@", mobile)
        let regextestCm = NSPredicate.init(format: "SELF MATCHES %@", cm)
        let regextestCu = NSPredicate.init(format: "SELF MATCHES %@", cu)
        let regextestCt = NSPredicate.init(format: "SELF MATCHES %@", ct)
        if ((regextestMobile.evaluate(with: num) == true) || (regextestCm.evaluate(with: num) == true) || (regextestCt.evaluate(with: num) == true) || (regextestCu.evaluate(with: num) == true)){
            return  true
        }else {
            return false
        }
    }

    // MARK: - 设置中国时区
    /// UTCDateString  UTC 字符时间转中国时间
    static func chineseTime(frome utcStr: String) -> String {
        let dateFormatter = DateFormatter.init()
        dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
        dateFormatter.timeZone  =   TimeZone(identifier: "Asia/Shanghai")  //中国时区
        
        
        let _date : Date = dateFormatter.date(from: utcStr)!
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        let dateStr = dateFormatter.string(from: _date)
        
        return dateStr
    }
    
    // MARK: - 计算字符串长宽
    /**
     @note 计算字符长宽
     @param  text - 内容
     @param  font - 字体大小
     @param  size - 最大范围(提供容器高宽度)
     
     @return CGSize
     *
     * @see creatorMask(view:action:）
     * @see UIView
     */
    static func getTextRectSize(text: NSString, font: CGFloat, size: CGSize) -> CGSize {
        let str: NSString = text
        
        let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: font)]
        // let attributes = NSDictionary(object: font, forKey: NSFontAttributeName)
        let option = UInt8(NSStringDrawingOptions.usesLineFragmentOrigin.rawValue) | UInt8(NSStringDrawingOptions.truncatesLastVisibleLine.rawValue) | UInt8(NSStringDrawingOptions.usesFontLeading.rawValue)
        //  size 为UILabel的宽度 ,及预设的一个高度，表示在这个范围内
        let rect: CGSize = str.boundingRect(with: size, options: NSStringDrawingOptions(rawValue: NSStringDrawingOptions.RawValue(option)), attributes: attributes, context: nil).size
        
        //        let width = str.size(withAttributes: [NSAttributedStringKey.font: UIFont.systemFont(ofSize: font)]).width
        return rect
    }
    
    
    
    /// 截取字符串 value == 需要截取的内容， character == 开始截取的字符
    static func suffixString(value:String, character: Character) -> String {
//        let index = value.lastIndex(of: "x")  //获取从后面开始计算的
        let index = value.firstIndex(of: character) // 获取从前面开始计算的某个字符下标
        let subStr = value.prefix(upTo: index!)
        
        return String(subStr)
    }
    
    
    static func interceptString(value: String, character: Character, isPrefix: Bool, isFirst: Bool) -> String {
    
         // 默认 isContain = false
        
//        var contain = false
//        if isContain == nil {
//            contain = false
//        }else  {
//            contain = isContain!
//        }
        
        
        var index: String.Index?
        if isFirst {
            index = value.firstIndex(of: character)  // 获取从前面开始计算的某个字符下标
        }else {
            index = value.lastIndex(of: character)  // 从后面
        }
        
        
            if isPrefix {
                let preStr  = value.prefix(upTo: index!)  // 截取前面部分, 不包括 character 内容
                return String(preStr)
            }else {
                
                let subStr = value.suffix(from: index!) // 截取后面部分
                return String(subStr)
            }
        
        
        
    }
 
    
    /// 字符串长度
    var length: Int {
        return self.characters.count
     }
    ///
    subscript (i: Int) -> String {
        return self[i ..< i + 1]
    }
    
    func substring(fromIndex: Int) -> String {
        return self[min(fromIndex, length) ..< length]
    }
    
    func substring(toIndex: Int) -> String {
        return self[0 ..< max(0, toIndex)]
    }
    
    subscript (r: Range<Int>) -> String {
        let range = Range(uncheckedBounds: (lower: max(0, min(length, r.lowerBound)), upper: min(length, max(0, r.upperBound))))
        let start = index(startIndex, offsetBy: range.lowerBound)
        let end = index(start, offsetBy: range.upperBound - range.lowerBound)
        return String(self[start ..< end])
    }

}


// MARK: - UIImageView
public extension UIImageView {
    public func imgName(name:String){
        self.image = UIImage(named: name)
        self.contentMode = UIViewContentMode.scaleAspectFit
    }
    
    public func img(url: String){
        let ph = UIImage(named: "pl.png") // pl 默认图片
        let imgUrl = URL(string: url)
        self.sd_setImage(with: imgUrl, placeholderImage: ph)
    }
    
    public func img(url: String, suc:@escaping (_ img: UIImage) -> ()){
        let ph = UIImage(named: "pl.png")
        let imgUrl = URL(string: url)
        self.sd_setImage(with: imgUrl, placeholderImage: ph) { (img, error, type, url) in
            if let img = img {
                suc(img)
            }
        }
    }
}

public extension UIImage {
    // ImageIO
    func resizeIO(size: CGSize) -> UIImage? {
        // guard语句判断其后的表达式布尔值为false时，才会执行之后代码块里的代码，如果为true，则跳过整个guard语句
        guard let data = UIImagePNGRepresentation(self) else { return nil}
        
        let maxPixelSize = max(size.width,size.height)
        
        //let imageSource = CGImageSourceCreateWithURL(url, nil)
        guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil) else {return nil}
        
        
        //kCGImageSourceThumbnailMaxPixelSize为生成缩略图的大小。当设置为800，如果图片本身大于800*600，则生成后图片大小为800*600，如果源图片为700*500，则生成图片为800*500
        let options: [NSString : Any] = [
            kCGImageSourceThumbnailMaxPixelSize : maxPixelSize,
            kCGImageSourceCreateThumbnailFromImageAlways : true
        ]
        
        let resizedImage = CGImageSourceCreateImageAtIndex(imageSource, 0, options as CFDictionary).flatMap{
            UIImage(cgImage: $0)
        }
        
        return resizedImage!
    }
    
    
    // 图片截取
        // 第一部分是图片尺寸的压缩
        class func resizeImage(originalImg: UIImage) -> UIImage {
            let width = originalImg.size.width
            let height = originalImg.size.height
            let scale = width/height
            var sizeChange = CGSize()
            
            if width <= 1280 && height <= 1280 { //a，图片宽或者高均小于或等于1280时图片尺寸保持不变，不改变图片大小
                return originalImg
            }else if width > 1280 || height > 1280 { //b,宽或者高大于1280，但是图片宽度高度比小于或等于2，则将图片宽或者高取大的等比压缩至1280
                
                if scale <= 2 && scale >= 1 {
                    let changedWidth: CGFloat = 1280
                    let changedheight: CGFloat = changedWidth / scale
                    sizeChange = CGSize(width: changedWidth, height: changedheight)
                }else if scale >= 0.5 && scale <= 1 {
                    let changedheight: CGFloat = 1280
                    let changedWidth: CGFloat = changedheight * scale
                    sizeChange = CGSize(width: changedWidth, height: changedheight)
                }else if width > 1280 && height > 1280 { //宽以及高均大于1280，但是图片宽高比大于2时，则宽或者高取小的等比压缩至1280
                    if scale > 2 { //高的值比较小
                        let changedheight: CGFloat = 1280
                        let changedWidth: CGFloat = changedheight * scale
                        sizeChange = CGSize(width: changedWidth, height: changedheight)
                    }else if scale < 0.5 { //宽的值比较小
                        let changedWidth: CGFloat = 1280
                        let changedheight: CGFloat = changedWidth / scale
                        sizeChange = CGSize(width: changedWidth, height: changedheight)
                    }
                }else { //d, 宽或者高，只有一个大于1280，并且宽高比超过2，不改变图片大小
                    return originalImg
                }
            }
            
            UIGraphicsBeginImageContext(sizeChange)
            //draw resized image on Context
            originalImg.draw(in: CGRect(x: 0, y: 0, width: sizeChange.width, height: sizeChange.height))
            //create UIImage
            let resizedImg = UIGraphicsGetImageFromCurrentImageContext()
            
            UIGraphicsEndImageContext()
            
            return resizedImg!
            
        }
        //图片压缩 1000kb以下的图片控制在100kb-200kb之间
        class func compressImageSize(image: UIImage) -> NSData {
            var zipImageData = UIImageJPEGRepresentation(image, 1.0)!
            let originalImgSize = zipImageData.count/1024 as Int  //获取图片大小
            
            print("原始大小: \(originalImgSize)")
            
            if originalImgSize > 1500 {
                zipImageData = UIImageJPEGRepresentation(image, 0.2)!
            }else if originalImgSize > 600 {
                zipImageData = UIImageJPEGRepresentation(image,0.4)!
            }else if originalImgSize > 400 {
                zipImageData = UIImageJPEGRepresentation(image,0.6)!
            }else if originalImgSize > 300 {
                zipImageData = UIImageJPEGRepresentation(image,0.7)!
            }else if originalImgSize>200 {
                zipImageData = UIImageJPEGRepresentation(image,0.8)!
            }
            
            return zipImageData as NSData
        }


    
}

public extension Date {
    /// 获取当前时间(String 类型)
    static func getCurrentDate() -> String? {
        let currentDate = Date()
        let dateStr = getFromString(date: currentDate)
        return dateStr
    }
    /// 计算当月的天数量
    static func getDaysInCurrentMonth() -> Int {
        let calendar  = Calendar.current
        let date = Date()
        let nowComps = calendar.dateComponents([.year, .month, .day], from: date)
        let year = nowComps.year
        let month = nowComps.month
        
        // 开始
        var startComps = DateComponents()
        startComps.day = 1
        startComps.month = month
        startComps.year = year
        
        // 结束
        var endComps = DateComponents()
        endComps.day = 1
        endComps.month = (month! == 12 ? 1 : month! + 1)
        endComps.year = (month! == 12 ? year! + 1 : year)
        
//        let startDate = calendar.dateFromComponents(startComps)
        let startDate = calendar.date(from: startComps)
        let endDate = calendar.date(from: endComps)
        
        let diff = calendar.dateComponents([.day], from: startDate!, to: endDate!)
        return diff.day!
    }
    
    /// 计算指定年、月的天数 , 例如：year = 2016, month = 2
    static func getDaysInMonth(year: Int, month: Int) -> Int {
         let calendar  = Calendar.current
        
        // 开始
        var startComps = DateComponents()
        startComps.day = 1
        startComps.month = month
        startComps.year = year
        
        // 结束
        var endComps = DateComponents()
        endComps.day = 1
        endComps.month = (month == 12 ? 1 : month + 1)
        endComps.year = (month == 12 ? year + 1 : year)
        
        //        let startDate = calendar.dateFromComponents(startComps)
        let startDate = calendar.date(from: startComps)
        let endDate = calendar.date(from: endComps)
        
        let diff = calendar.dateComponents([.day], from: startDate!, to: endDate!)
        return diff.day!
    }

    /// Sting转 Date
    static func getFromDate(dateString: String) -> Date? {
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let newDate = dateFormatter.date(from: dateString)
        
        return newDate
    }
    ///  Date 转 String
    /**
      *  - Parameters:
      *  - date: Date类型
      *  - dateFormat: 格式化样式默认“yyyy-MM-dd”
      *  - Returns: 日期字符串
      */
    static func getFromString(date: Date, dateFormat: String = "yyyy-MM-dd HH:mm:ss") -> String? {
        let _titmeZone = TimeZone(identifier: "Asia/Shanghai") // 公 UTC
        let _formatter = DateFormatter()
        _formatter.timeZone = _titmeZone
        _formatter.locale = Locale(identifier: "zh_CN") //Locale.current
        _formatter.dateFormat = dateFormat
        let _dateString = _formatter.string(from: date)
        return _dateString //_date.components(separatedBy: " ").first!
    }
    
    
    //MARK:获取当前时间与一个时间的差值
    static  func getTimeDifferentWith(date: String) -> String {
        
        let dateFormatter = DateFormatter()
        
        dateFormatter.dateStyle = .medium
        
        dateFormatter.timeStyle = .short
        
        dateFormatter.dateFormat = "YYYY-MM-dd HH:mm:ss"
        
        dateFormatter.timeZone = TimeZone.init(identifier: "Asia/Beijing")//设置时区
        
        print("当前时区--->\(TimeZone.current)---->\(NSTimeZone.system)")
        
        
        
        let dateModel = dateFormatter.date(from: date)//按照格式设置传入的date时间
        
        let dateNow = dateFormatter.date(from: Date.getCurrentDate()!)
        
        let timeModel = NSString.init(format: "%ld", Int(dateModel!.timeIntervalSince1970))//计算传入时间的时间戳
        
        let timeNow = NSString.init(format: "%ld", Int(dateNow!.timeIntervalSince1970))//计算当前时间的时间戳
        
        
        
        let time = (timeNow.integerValue - timeModel.integerValue) / 60//计算时差
        
        if time > 60 {
            
            return String.init(format: "%ld小时%ld分钟前", time / 60, time % 60)
            
        } else {
            
            return String.init(format: "%ld分钟前", time % 60)
            
        }
 
    }
    
    
    //MARK: -根据后台时间戳返回几分钟前，几小时前，几天前
    static func updateTimeToCurrennTime(timeStamp: Double) -> String {
        //获取当前的时间戳
        let currentTime = Date().timeIntervalSince1970
        print(currentTime, timeStamp, "sdsss")
        //时间戳为毫秒级要 ／ 1000， 秒就不用除1000，参数带没带000
        let timeSta:TimeInterval = TimeInterval(timeStamp / 1000)
        //时间差
        let reduceTime : TimeInterval = currentTime - timeSta
        //时间差小于60秒
        if reduceTime < 60 { return "刚刚" }
        //时间差大于一分钟小于60分钟内
        let mins = Int(reduceTime / 60)
        if mins < 60 { return "\(mins)分钟前" }
        let hours = Int(reduceTime / 3600)
        if hours < 24 { return "\(hours)小时前" }
        let days = Int(reduceTime / 3600 / 24)
        if days < 30 { return "\(days)天前" }
        //不满足上述条件---或者是未来日期-----直接返回日期
        let date = NSDate(timeIntervalSince1970: timeSta)
        let dfmatter = DateFormatter()
        //yyyy-MM-dd HH:mm:ss dfmatter.dateFormat="yyyy年MM月dd日 HH:mm:ss"
        return dfmatter.string(from: date as Date)
    }

    //MARK: - 时间戳 转时间,String 类型。 例如：
    static func timeStampToString(timeStamp: String) -> String {
        let string =  NSString(string: timeStamp)
        let timeSta: TimeInterval =  TimeInterval(string.doubleValue) ///string.doubleValue
        
        
        
        let date = NSDate(timeIntervalSince1970: timeSta)
        let dfmatter = DateFormatter()
        dfmatter.dateFormat="yyyy-MM-dd HH:mm:ss"
//        print(dfmatter.stringFromDate(date))
        return dfmatter.string(from: date as Date)
    }

     //MARK: - 时间 转 时间戳,String 类型。 例如：
    static func stringToTimeStamp(stringTime:String)->String {
        
        var dfmatter = DateFormatter()
        dfmatter.dateFormat="yyyy-MM-dd HH:mm:ss"
        var date = dfmatter.date(from: stringTime) //string(from: stringTime)     ///.dateFromString(stringTime)
        
        var dateStamp: TimeInterval = date!.timeIntervalSince1970
        
        var dateSt:Int = Int(dateStamp)
        return String(dateSt)
        
    }
}




public extension UIView {


//    class func creatorMask(view: UIView!, _ action: Selector) {
//        let subView = UIView()
//        subView.frame = CGRect.init(origin: CGPoint.zero, size: UIScreen.main.bounds.size)
//        view.addSubview(subView)
//        
//        subView.backgroundColor = .red
//        subView.alpha = 0.2
//    }

    
}

public extension String {
 
}


public extension UIButton {
    
    /// 给UIButton添加个属性(用来传值) - Dictionary
    struct RuntimeKey {
        // DictionaryKey        // 不安全的原始指针
        static let dicKey = UnsafeRawPointer(bitPattern: "dicKey".hashValue)
    }
    
    var dictionary: [String:Any]? {
        set {
            objc_setAssociatedObject(self, UIButton.RuntimeKey.dicKey!, newValue, .OBJC_ASSOCIATION_COPY_NONATOMIC)
        }
        get {
            return objc_getAssociatedObject(self, UIButton.RuntimeKey.dicKey!) as? [String : Any]
        }
    }
    
    
}




